(defun euler1(max factors)
  "call using (euler1 999 (list 3 5)"
  "this will return nil if invalid arguments are supplied"
  "it removes any duplicates from the factors list"
  (setf uniqueFactors (remove-duplicates factors))
  (if (and (containsOnlyPositiveIntegers uniqueFactors) (ispositveinteger max))
      (-
       (TotalSumMultiplesBelow max uniqueFactors)
       (TotalSumMultiplesBelow max (commonMultiples uniqueFactors)))))

(defun isInteger(x)
  (typep x 'integer))

(defun isPositveInteger(x)
  (and (isinteger x)
       (> x 0)))

(defun containsOnlyPositiveIntegers(input)
  "given a list, check all elements"
  (if (= (length (remove-if-not #'isPositveInteger input)) (length input)) T nil))

(defun commonMultiples(factors)
  "returns a list of the lowest common multiples from the factors list"
  "a combination"
  (cond ((= (length factors) 2) (list (* (car factors) (cadr factors))))
        ((> (length factors) 2) (let ((child (commonMultiples (cdr factors)))) 
                                  (append 
                                   child 
                                   (loop for f1 in (cdr factors) 
                                         collect 
                                         (* (car factors) f1)))))))

(defun sumMultiples (factor max)
  "this returns the sum of multiples <= the max"
  (/ (* (/ (- max (mod max factor)) factor) (+ (- max (mod max factor)) factor)) 2))

(defun TotalSumMultiplesBelow (max factors)
  "this totals the sumsofmultiples of a list of factors <= the max number"
  (reduce #'+ (maplist #'(lambda (x) (sumMultiples (first x) max)) factors)))

(defun testC()
  (print (euler1 most-positive-fixnum (list 3 5)))
  (print (euler1 9999 (list 3 0)))
  (print (euler1 9999 (list 3 5)))
  (print (euler1 9999 (list 3.0 5)))
  (print (euler1 9999 (list "a" "b")))
  (print (euler1 9999 (list 0 0)))
  (print (euler1 9999 (list -1 0)))
  (print (euler1 -9999 (list -1 0)))
  (print (euler1 -9999 (list -1 0)))
  (euler1 999 (list 3 5 10000)))

